package com.sscl.baselibrary.exts

import androidx.annotation.Size
import com.sscl.baselibrary.utils.isZhCn
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import java.util.regex.Pattern


/**
 * StringExt
 *
 * String 扩展类
 * @author jackie Penghe
 * @date 2024/9/4
 */



private const val IP_V4_REGEX =
    "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$"

/**
 * 将字符串转为ASCII码十六进制字符串
 */
fun String?.toAsciiHexString(): String? {
    this ?: return null
    val byteArray = toByteArray(StandardCharsets.US_ASCII)
    return byteArray.toHexStringWithSpace()
}

/**
 * 十六进制字符串转换为标准字符串
 * 十六进制字符串之间没有任何分割符，如:[616C6B]
 */
fun String?.toStandardString(): String? {
    this ?: return null
    val str = "0123456789ABCDEF"
    val cache: CharArray = toCharArray()
    val byteArray = ByteArray(length / 2)
    var n: Int
    for (i in byteArray.indices) {
        n = str.indexOf(cache[2 * i]) * 16
        n += str.indexOf(cache[2 * i + 1])
        byteArray[i] = (n and 0xff).toByte()
    }
    return String(byteArray)
}

/**
 * 十六进制字符串转换为标准字符串
 * 十六进制字符串之间没有任何分割符，如:[616C6B]
 */
fun String?.fromHexStringWithoutDelimiterToByteArray(): ByteArray? {
    this ?: return null
    var m: Int
    var n: Int
    val l: Int = length / 2
    val ret = ByteArray(l)
    for (i in 0 until l) {
        m = i * 2 + 1
        n = m + 1
        val integer: Int = Integer.decode("0x" + substring(i * 2, m) + substring(m, n))
        ret[i] = integer.toByte()
    }
    return ret
}

/**
 * 将十六进制字符串用指定的 [character]字符分割
 */
fun String.formatToHex(character: Char, uppercase: Boolean = true): String {
    val characterString = character.toString()
    val cache = if (contains(characterString)) {
        replace(characterString, "")
    } else {
        this
    }
    if (cache.isEmpty()) {
        return ""
    }
    val charArray = cache.toCharArray()
    val result = StringBuilder()
    for (i in charArray.indices) {
        result.append(charArray[i])
        if (i % 2 == 1 && i != charArray.size - 1) {
            result.append(character)
        }
    }
    val resultString = result.toString()
    return if (uppercase) {
        resultString.uppercase()
    } else {
        resultString
    }
}

/**
 * 将IPV4字符串转为byte数组
 */
fun String?.toIpV4ByteArray(): ByteArray? {
    this ?: return null
    if (!isIpv4String()) {
        return null
    }
    val split: Array<String> = split("\\.").toTypedArray()
    val result = ByteArray(4)
    for (i in result.indices) {
        result[i] = split[i].toInt().toByte()
    }
    return result
}

/**
 * 将带分隔符的十六进制字符串转为byte数组
 *
 * @return byte数组
 */
fun String?.fromHexStringWithSpaceToByteArray(): ByteArray? {
    return fromHexStringWithDelimiterToByteArray(" ")
}

/**
 * 将带分隔符的十六进制字符串转为byte数组
 *
 * @return byte数组
 */
fun String?.fromHexStringWithDelimiterToByteArray(delimiter: String): ByteArray? {
    this ?: return null
    //将获取到的数据以空格为间隔截取成数组
    val split: Array<String> = split(delimiter).toTypedArray()
    val length: Int = split.size

    //新建一个byte数组
    val result = ByteArray(length)
    var cache: Int
    //用循环使截取出来的16进制字符串数组中的字符串转为byte,并固定for循环次数为定义的长度(这样的话，即使String数组长度大于定义的长度，也不会发生数组越界异常)
    for (i in result.indices) {
        try {
            cache = split[i].toInt(16)
        } catch (e: NumberFormatException) {
            e.printStackTrace()
            return null
        }
        result[i] = cache.toByte()
    }
    return result
}

/**
 * 检查是否符合IPv4格式文本
 *
 * @return true表示符合
 */
fun String?.isIpv4String(): Boolean {
    this ?: return false
    val pattern = Pattern.compile(IP_V4_REGEX)
    val matcher = pattern.matcher(this)
    return matcher.matches()
}

/**
 * 字符串转换成byte数组（数组长度最长为byteArrayLength）
 *
 * @param charset         编码方式
 * @param byteArrayLength 数组长度的最大值（数组长度超过该值会被截取，长度不足该值为数组原长度）
 * @return 转换后获得的byte[]
 */
fun String?.getByteArray(
    charset: Charset = StandardCharsets.UTF_8,
    @Size(min = 0) byteArrayLength: Int = this?.length ?: 0
): ByteArray? {
    this ?: return null
    val data: ByteArray
    if (byteArrayLength > 0) {
        if (length > byteArrayLength) {
            data = ByteArray(byteArrayLength)
            System.arraycopy(toByteArray(charset), 0, data, 0, byteArrayLength)
        } else {
            data = toByteArray(charset)
        }
    } else {
        data = toByteArray(charset)
    }
    return data
}

/**
 * 字符串转换成byte数组（数组长度最长为byteArrayLength）
 *
 * @param byteArrayLength 数组长度的最大值（数组长度超过该值会被截取，长度不足该值为数组原长度）
 * @return 转换后获得的byte[]
 */
fun String?.getByteArray(
    @Size(min = 0) byteArrayLength: Int = this?.length ?: 0
): ByteArray? {
    return getByteArray(StandardCharsets.UTF_8, byteArrayLength)
}

/**
 * 字符串转换成byte数组，自动判断中文简体语言环境，在中文简体下，自动以GBK方式转换（数组长度最长为byteArrayLength）
 *
 * @param byteArrayLength 数组长度的最大值（数组长度超过该值会被截取，长度不足该值为数组原长度）
 * @return 转换后获得的byte[]
 */
fun String?.getByteArrayAutoGbk(byteArrayLength: Int): ByteArray? {
    return if (isZhCn()) {
        getByteArray(Charset.forName("GBK"), byteArrayLength)
    } else {
        getByteArray(byteArrayLength)
    }
}

/**
 * String的字符串转换成unicode的String
 *
 * @return String 每个unicode之间无分隔符
 */
fun String.stringToUnicode(): String {
    var c: Char
    val str: StringBuilder = StringBuilder()
    var intAsc: Int
    var strHex: String?
    for (i in this.indices) {
        c = this[i]
        intAsc = c.code
        strHex = Integer.toHexString(intAsc)
        if (intAsc > 128) {
            str.append("\\u").append(strHex)
        } else {
            str.append("\\u00").append(strHex)
        }
    }
    return str.toString()
}

/**
 * unicode的String转换成String的字符串
 *
 * @param hex 16进制值字符串 （一个unicode为2byte）
 * @return String 全角字符串
 */
fun String.unicodeToString(): String {
    val t: Int = this.length / 6
    val str: StringBuilder = StringBuilder()
    for (i in 0 until t) {
        val s: String = this.substring(i * 6, (i + 1) * 6)
        // 高位需要补上00再转
        val s1: String = s.substring(2, 4) + "00"
        // 低位直接转
        val s2: String = s.substring(4)
        // 将16进制的string转为int
        val n: Int = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16)
        // 将int转换为字符
        val chars: CharArray = Character.toChars(n)
        str.append(String(chars))
    }
    return str.toString()
}
